環境採用 OpenStack 三個 Instance ,也可以嘗試使用三臺實體機器進行建置:
主機名稱 | IP Address | 角色 |
---|---|---|
Ehtereum-1 | 10.28.120.32 | Node |
Ethereum-2 | 10.28.120.29 | Node |
Ethereum-3 | 10.28.120.35 | Miner |
Node 表示一個使用者帳號,提供使用者進行交易或其餘操作使用,Miner 表示區塊挖掘者,針對乙太鏈所使用的演算法進行區塊挖掘,以下統一稱為節點。
首先使用 go-ethereum 官方安裝指令進行套件安裝。
$ sudo apt-get install software-properties-common
...
$ sudo add-apt-repository -y ppa:ethereum/ethereum
...
$ sudo apt-get update
...
$ sudo apt-get install ethereum
...
安裝完畢後,在所有節點上建立乙太鏈帳號:
$ geth --datadir ./data account new
WARN [07-17|05:59:19] No etherbase set and no accounts found as default
Your new account is locked with a password. Please give a password. Do not forget this password.
Passphrase:
Repeat passphrase:
Address: {b581d6307e78da1412875e21850c0ebcdd0ac37a}
註冊帳號同時要給予每個帳號一個密碼,切記密碼必須記住,否則往後無法進行交易,因為交易前需要使用密碼將帳號 unlock。
帳號列表如下:
接下來建立創世區塊,也就是整個私有乙太鏈的第一個區塊,可以透過 go ethereum 內建的指令建立:
$ puppeth
+-----------------------------------------------------------+
| Welcome to puppeth, your Ethereum private network manager |
| |
| This tool lets you create a new Ethereum network down to |
| the genesis block, bootnodes, miners and ethstats servers |
| without the hassle that it would normally entail. |
| |
| Puppeth uses SSH to dial in to remote servers, and builds |
| its network components out of Docker containers using the |
| docker-compose toolset. |
+-----------------------------------------------------------+
Please specify a network name to administer (no spaces, please)
> imac
可以依照自己的喜好,自行定義私有區塊鏈名稱,這裡我們取名為 imac
What would you like to do? (default = stats)
1. Show network stats
2. Configure new genesis
3. Track new remote server
4. Deploy network components
> 2
這裡選擇 2,建立一個新的創世區塊
Which consensus engine to use? (default = clique)
1. Ethash - proof-of-work
2. Clique - proof-of-authority
> 1
共識機制,這裡選擇 1,採用的是 PoW
Which accounts should be pre-funded? (advisable at least one)
> 0xb581d6307e78da1412875e21850c0ebcdd0ac37a
> 0x36bdc7ad6a91569de06e97ae4da81b3aea281a7c
> 0x
這裡可以預先給一些帳號 ether(交易的錢),依照自己的需求自行定義
Specify your chain/network ID if you want an explicit one (default = random)
>
Network ID 這裡採用預設的 Random
Anything fun to embed into the genesis block? (max 32 bytes)
>
留空
What would you like to do? (default = stats)
1. Show network stats
2. Save existing genesis
3. Track new remote server
4. Deploy network components
> 2
選擇 2,存檔
Which file to save the genesis into? (default = imac.json)
>
留空,採用預設名稱
What would you like to do? (default = stats)
1. Show network stats
2. Save existing genesis
3. Track new remote server
4. Deploy network components
> ^C
Ctrl + C 直接退出
確認當下目錄產生 imac.json 檔案:
$ ls
bin data etc imac.json lib64 mnt proc run srv tmp var
boot dev home lib media opt root sbin sys usr
初始化每個節點:
$ geth --datadir data init imac.json
INFO [07-17|06:33:06] Allocated cache and file handles database=/data/geth/chaindata cache=16 handles=16
INFO [07-17|06:33:06] Writing custom genesis block
INFO [07-17|06:33:06] Successfully wrote genesis state database=chaindata hash=7d94c2…480416
INFO [07-17|06:33:06] Allocated cache and file handles database=/data/geth/lightchaindata cache=16 handles=16
INFO [07-17|06:33:06] Writing custom genesis block
INFO [07-17|06:33:06] Successfully wrote genesis state database=lightchaindata hash=7d94c2…480416
分別在兩個 Node 上執行 geth:
$ screen
$ geth --datadir ./data --networkid 77777 --port 2000 --rpc --rpcapi=db,eth,net,web3,personal,web3 --rpcaddr=0.0.0.0 console
這裡使用 screen 的目的是開啟一個子 terminal 執行指令,並且使用
exit
指令返回父 terminal
在 Miner 節點的 screen 模式下執行:
$ screen
$ geth --datadir ./data --networkid 7777 --port 2000 --rpc --rpcapi=db,eth,net,web3,personal,web3 --rpcaddr=0.0.0.0 --unlock 36bdc7ad6a91569de06e97ae4da81b3aea281a7c console
...
Passphrase:
...
這裡需要輸入 minier 的密碼進行 unlock 動作
返回 Ethereum-1 的 Terminal 可以由原先的訊息中找到其中一段如下:
...
INFO [07-17|06:41:16] UDP listener up self=enode://fbf9c7b7b8fbe0f6813ef4e86e418fedcc807af27f6a98d4ac0c647f737e3b3a8d55b54cd24f16dfb4fef4b052289e6a49e6b419f179ee4c6a89adc7670940f4@[::]:2000
這裡我們需要將其他節點與 Ethereum-1 串到同一個私有乙太鏈上,所以我們需要將上方複製的訊息在其他節點透過 addPeer 方式進行串接:
$ admin.addPeer("enode://fbf9c7b7b8fbe0f6813ef4e86e418fedcc807af27f6a98d4ac0c647f737e3b3a8d55b54cd24f16dfb4fef4b052289e6a49e6b419f179ee4c6a89adc7670940f4@10.28.120.32:2000")
注意,這裡需要將 [::] 改成 Ethereum-1 的 IP Address
完成後,回到 Ethereum-1 使用 admin.peers 查看是否有其他三個節點的資訊。
[{
caps: ["eth/63"],
id: "0d12bbf86a54109d5960ef01407d0d911053da19a0fa65083925bac45cc2003b315c4efa09214b3f12554777301b9626e78cac05eebf9eec2bccb785f50e6b89",
name: "Geth/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1",
network: {
localAddress: "10.28.120.32:2000",
remoteAddress: "10.28.120.29:53054"
},
protocols: {
eth: {
difficulty: 1048576,
head: "0x7d94c2e496b3717b8b6d82f6410a174424f034ad7c811080861ccb1f31480416",
version: 63
}
}
}, {
caps: ["eth/63"],
id: "3d1a2c09dcaedbced1e805f6a87f2bd5b6c5e869ac2133522c7236678fe41695b210e52b6bc05cdc41e756639bb15eb13993608d433c122852764e2d5a266fc6",
name: "Geth/v1.6.7-stable-ab5646c5/linux-amd64/go1.8.1",
network: {
localAddress: "10.28.120.32:2000",
remoteAddress: "10.28.120.35:42872"
},
protocols: {
eth: {
difficulty: 1048576,
head: "0x7d94c2e496b3717b8b6d82f6410a174424f034ad7c811080861ccb1f31480416",
version: 63
}
}
}]
切換到 Miner 節點進行挖礦:
$ miner.start()